package org.yeauty.test;

import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.*;

public class OperationNettyClientHandler extends SimpleChannelInboundHandler<Object> {


    private WebSocketClientHandshaker webSocketClientHandshaker;
    private ChannelFuture channelFuture;

    public OperationNettyClientHandler(WebSocketClientHandshaker webSocketClientHandshaker) {
        this.webSocketClientHandshaker = webSocketClientHandshaker;
    }

    public ChannelFuture channelFuture() {
        return channelFuture;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        channelFuture = ctx.newPromise();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        webSocketClientHandshaker.handshake(ctx.channel());
        System.out.println("operation netty client send websocket handshake request.");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("netty client disconnected.");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();

        if (!webSocketClientHandshaker.isHandshakeComplete()) {
            try {
                webSocketClientHandshaker.finishHandshake(channel, (FullHttpResponse) msg);
                System.out.println("netty client connected.");
                ((ChannelPromise) channelFuture).setSuccess();
            } catch (WebSocketHandshakeException e) {
                System.err.println("websocket handshake failed." + e);
                ((ChannelPromise) channelFuture).setFailure(e);
            }
            return;
        }

        if (msg instanceof FullHttpResponse) {
            FullHttpResponse response = (FullHttpResponse) msg;
            throw new IllegalStateException("not supported http response.");
        }

        WebSocketFrame webSocketFrame = (WebSocketFrame) msg;
        if (webSocketFrame instanceof TextWebSocketFrame) {
            TextWebSocketFrame textWebSocketFrame = (TextWebSocketFrame) webSocketFrame;
            System.out.println("receives text frame: " + textWebSocketFrame.text());
        } else if (webSocketFrame instanceof PongWebSocketFrame) {
            System.out.println("receives pong frame: " + webSocketFrame);
        } else if (webSocketFrame instanceof CloseWebSocketFrame) {
            System.out.println("receives close websocket frame, netty client is closing.");
            channel.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("operation netty client handler exception caught." + cause);
        if (!channelFuture.isDone()) {
            ((ChannelPromise) channelFuture).setFailure(cause);
        }
        ctx.close();
    }
}
